package NG::Gen::Users::Inventory;
use strict;
use warnings;
use utf8;
#use NG::Gen::Users::Constants;

sub add_leader {
	my $self = shift;
	my $proto = shift;
	unless($proto){
		return 0;
	}
	my $l = $self->leaders;
	unless($proto->{max} and $proto->{max} > $l->length($proto->{entry})){
		return 0;
	}
	my $entry = $l->insert({proto_id=>$proto->{entry}});
	if($entry){
		return $l->get_by_entry($entry);
	}else{
		return 0;
	}
}
sub add_unit {
	my $self = shift;
	my $leader = shift;
	my $proto = shift;
	my $count = shift || 1;
	unless($leader && $leader->user_id == $self->obj_id){
		return "bad leader";
	}
	unless($proto){
		return "bad proto";
	}
	#unless($leader->proto->{type} == $self->{parent}{user_config}{inventory}{base_leader_type}){
	#	return "cannot add to this leader";
	#}
	my $unit = $leader->units->get_by_key($proto->{entry},1);
	my $current = @$unit && $unit->[0]->count;
	unless($proto->{max} and $proto->{max} >= $current + $count){
		return "max number unit";
	}
	if(@$unit){
		$unit->[0]->count($current + $count);
	}else{
		$leader->units->insert({proto_id=>$proto->{entry},count=>$count});
	}
	return 0;
}
sub add_item {
	my $self = shift;
	my $leader = shift;
	my $proto = shift;
	my $count = shift || 1;
	unless($leader && $leader->user_id == $self->obj_id){
		return "bad leader";
	}
	#unless($leader->proto->{type} == $self->{parent}{user_config}{inventory}{base_leader_type}){
	#	return "cannot add to this leader";
	#}
	unless($proto){
		return "bad proto";
	}
	my $litems = $leader->items;
	my $current = $litems->length($proto->{entry});
	unless($proto->{max} and $proto->{max} >= $current + $count){
		return "max number unit";
	}
	$litems->begin_transaction;
	for(1 .. $count){
		$litems->insert({proto_id=>$proto->{entry}});
	}
	$litems->commit;
	return 0;
}
sub transfer_unit {
	my $self = shift;
	my $leader_from = shift;
	my $leader_to = shift;
	my $proto = shift;
	my $count = shift || 1;
	if($count < 0){
		return 0;
	}
	unless($leader_from && $leader_from->user_id == $self->obj_id){
		return "bad leader_from";
	}
	unless($leader_to && $leader_to->user_id == $self->obj_id){
		return "bad leader_to";
	}
	unless($proto){
		return "bad proto";
	}
	#unless($leader_from->proto->{type} == $self->{parent}{user_config}{inventory}{base_leader_type}){
	#	return "cannot transfer from this leader ".$leader_from->proto->{type};
	#}

	$leader_from = $leader_from->units;
	my $unit_from = $leader_from->get_by_key($proto->{entry},1);
	my $current_from = @$unit_from && $unit_from->[0]->count;
	if($current_from < $count){
		$count = $current_from;
		#return "leader_from has only $current_from, but need $count";
	}

	$leader_to = $leader_to->units;
	my $unit_to = $leader_to->get_by_key($proto->{entry},1);
	my $current_to = @$unit_to && $unit_to->[0]->count;
	unless($proto->{max} and $proto->{max} >= $current_to + $count){
		return "max number unit";
	}
	if($count > 0){
		$unit_from->[0]->count($current_from - $count);
		if(@$unit_to){
			$unit_to->[0]->count($current_to + $count);
		}else{
			$leader_to->insert({proto_id=>$proto->{entry},count=>$count});
		}
	}
	return 0;
}
sub transfer_item {
	my $self = shift;
	my $leader_from = shift;
	my $leader_to = shift;
	my $item_entry = shift;
	unless($leader_from && $leader_from->user_id == $self->obj_id){
		return "bad leader_from";
	}
	unless($leader_to && $leader_to->user_id == $self->obj_id){
		return "bad leader_to";
	}
	unless($item_entry){
		return "bad item";
	}
	#unless($leader_from->proto->{type} == $self->{parent}{user_config}{inventory}{base_leader_type}){
	#	return "cannot transfer from this leader ".$leader_from->proto->{type};
	#}

	$leader_from = $leader_from->items;
	my $item_from = $leader_from->get_by_entry($item_entry);
	unless($item_from){
		return "leader_from has not entry $item_entry";
	}

	$leader_to = $leader_to->items;
	my $count_to = $leader_to->length($item_from->proto_id);
	my $max = $item_from->proto->{max};
	unless($max and $max > $count_to){
		return "max number unit";
	}

	$item_from->remove;
	$leader_to->insert($item_from->data);
	return 0;
}
sub inventory_after_create {
	my $self = shift;
	my $ac = $self->{parent}{user_config}{inventory}{after_create};
	my $rl = $self->{parent}{app}->reference("leaders");
	my $ru = $self->{parent}{app}->reference("units");
	my $ri = $self->{parent}{app}->reference("items");
	for my $l_desc(@$ac){
		my $proto = $rl->get_by_key($l_desc->{type});
		my $leader = $self->add_leader($proto);
		unless($leader){
			return "error create leader";
		}
		if($l_desc->{units}){
			for my $u_desc(@{$l_desc->{units}}){
				my $proto = $ru->get_by_key($u_desc->{type});
				$self->add_unit($leader,$proto,$u_desc->{count});
			}
		}
		if($l_desc->{items}){
			for my $i_desc(@{$l_desc->{items}}){
				my $proto = $ri->get_by_key($i_desc->{type});
				$self->add_item($leader,$proto);
			}
		}
	}
	return undef;
}
1;
